package com.witdata.security.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import com.witdata.mysql.base.service.UserBaseService;
import com.witdata.mysql.base.service.UserRoleBaseService;
import com.witdata.common.domain.Status;
import com.witdata.common.domain.dto.CaptchaDto;
import com.witdata.common.domain.dto.UserRoleDto;
import com.witdata.mysql.domain.entity.TUser;
import com.witdata.mysql.domain.entity.TUserRole;
import com.witdata.common.domain.req.LoginRequest;
import com.witdata.common.domain.req.RegisterRequest;
import com.witdata.common.domain.res.LoginResponse;
import com.witdata.common.exception.GlobalException;
import com.witdata.common.util.CaptchaUtils;
import com.witdata.common.util.PasswordUtils;
import com.witdata.common.util.SnowflakeUtils;
import com.witdata.common.mapper.UserMapper;
import com.witdata.common.service.ImageService;
import com.witdata.security.domain.LoginUser;
import com.witdata.security.service.AuthService;
import com.witdata.security.utils.TokenUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {
    private final AuthenticationManager authenticationManager;
    private final UserBaseService userBaseService;
    private final SnowflakeUtils snowflakeUtils;
    private final TokenUtils tokenUtils;
    private final CaptchaUtils captchaUtils;
    private final ImageService imageService;
    private final UserRoleBaseService userRoleBaseService;

    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        LoginResponse loginResponse = new LoginResponse();
        // 创建认证对象
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
        // 利用认证信息，执行认证操作
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        Object principal = authentication.getPrincipal();
        if (principal instanceof LoginUser loginUser) {
            loginResponse.setToken(tokenUtils.createToken(loginUser));
        }
        return loginResponse;
    }

    @Override
    public void register(RegisterRequest registerRequest) {
        if (ObjectUtils.isEmpty(registerRequest.getUser())) throw new GlobalException(Status.PARAMERROR);
        if (ObjectUtils.isEmpty(registerRequest.getUser().getUsername()) || ObjectUtils.isEmpty(registerRequest.getUser().getPassword())) throw new GlobalException(Status.USERNAMEPASSWORDNOTFOUND);
        boolean exists = userBaseService.exists(new QueryWrapper().eq("username", registerRequest.user.getUsername()));
        if(exists) throw new GlobalException(Status.USERALREADYFOUND);
        Long userId = snowflakeUtils.nextId();
        String avatar = imageService.uploadAvatar(userId, registerRequest.user.getAvatar());
        String encodePassword = PasswordUtils.encode(registerRequest.user.getPassword());
        // 设置加密后的密码
        registerRequest.user.setPassword(encodePassword);
        // 转换为TUser
        TUser tUser = TUser.builder()
                .nickname(registerRequest.user.getNickname())
                .username(registerRequest.user.getUsername()).password(encodePassword)
                .phone(registerRequest.user.getPhone()).email(registerRequest.user.getEmail())
                .avatar(avatar)
                .build();
        tUser.setId(userId);
        tUser.setCreateTime(LocalDateTime.now());
        boolean save = userBaseService.save(tUser);
        if (!save) throw new GlobalException(Status.USERREGISTERERROR);
    }

    @Override
    public CaptchaDto getCaptcha() {
        return captchaUtils.getCaptcha();
    }

    @Override
    public void saveUserRole(UserRoleDto userRole) {
        TUserRole tUserRole = UserMapper.INSTANCE.toTUserRole(userRole);
        tUserRole.setId(snowflakeUtils.nextId());
        userRoleBaseService.save(tUserRole);
    }

    @Override
    public void logout() {
        boolean removed = tokenUtils.removeToken();
        if (!removed) throw new GlobalException(Status.TOKENREMOVEERROR);
    }

}
